package com.ivncorp.evnproject;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import com.google.maps.android.clustering.ClusterManager.OnClusterClickListener;
import com.google.maps.android.clustering.ClusterManager.OnClusterItemClickListener;
import com.google.maps.android.clustering.view.DefaultClusterRenderer;
import com.ivncorp.evnproject.adapter.MapSearchAdapter;
import com.ivncorp.evnproject.data.DataBaseHandler;
import com.ivncorp.evnproject.helpers.Variables;
import com.ivncorp.evnproject.map.ObjectMap;
import com.ivncorp.evnproject.model.UploadTable;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;

public class FragmentMap extends Fragment {

	private ClusterManager<ObjectMap> mClusterManager;
	private DataBaseHandler db;
	private GoogleMap mMap;
	private ObjectMap myObject;
	private Broasdcast broasdcast;
	private EditText txtSearch;
	private ListView listView;
	private MapSearchAdapter adapter;
	private List<ObjectMap> listSeached = new ArrayList<ObjectMap>();
	private Button btnClear;
	List<UploadTable> listuploadtable;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		broasdcast = new Broasdcast();
		getActivity()
				.registerReceiver(broasdcast, new IntentFilter("loadData"));
	}

	protected int getLayoutId() {
		return R.layout.layout_map;
	}

	protected GoogleMap getMap() {
		setUpMapIfNeeded();
		return mMap;
	}

	private void setUpMapIfNeeded() {
		if (mMap != null) {
			return;
		}
		try {
			mMap = ((SupportMapFragment) getActivity().getSupportFragmentManager()
					.findFragmentById(R.id.map)).getMap();	
		} catch (Exception e) {
			// TODO: handle exception
		}
		if (mMap != null) {
			mMap.setMyLocationEnabled(true);
			mMap.getUiSettings().setZoomControlsEnabled(false);
			startDemo();
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		setUpMapIfNeeded();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		getActivity().unregisterReceiver(broasdcast);
	}

	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View view = inflater.inflate(getLayoutId(), container, false);
		db = new DataBaseHandler(getActivity());
		setUpMapIfNeeded();

		// Get the button view
		View locationButton = ((View) view.findViewById(1).getParent())
				.findViewById(2);

		// and next place it, for exemple, on bottom right (as Google Maps app)
		RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) locationButton
				.getLayoutParams();
		// position on right bottom
		rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
		rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
		rlp.setMargins(0, 0, 30, 30);

		txtSearch = (EditText) view.findViewById(R.id.txtMap);
		listView = (ListView) view.findViewById(R.id.listMaps);
		btnClear = (Button) view.findViewById(R.id.btnMapsClear);

		adapter = new MapSearchAdapter(getActivity().getApplicationContext(),
				listSeached);
		listView.setAdapter(adapter);

		getActivity().getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

		// change text
		txtSearch.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				String key = txtSearch.getText().toString();
				if (!key.isEmpty()) {
					search(key);
					adapter.notifyDataSetChanged();
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				if (!listView.isShown()) {
					listView.setVisibility(View.VISIBLE);
				}
				if (txtSearch.getText().toString().isEmpty()) {
					listView.setVisibility(View.GONE);
				}
			}
		});

		btnClear.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				txtSearch.setText("");
			}
		});

		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {

				mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(listSeached
						.get(position).getPosition(), 15f));

				listView.setVisibility(View.GONE);

			}

		});

		new Variables(mMap);

		return view;
	}

	class Maprender extends DefaultClusterRenderer<ObjectMap> {

		public Maprender(Context context, GoogleMap map,
				ClusterManager<ObjectMap> clusterManager) {
			super(context, map, clusterManager);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected boolean shouldRenderAsCluster(Cluster<ObjectMap> cluster) {
			// TODO Auto-generated method stub
			return cluster.getSize() > 1;
		}

	}

	protected void startDemo() {
		getMap().moveCamera(
				CameraUpdateFactory.newLatLngZoom(new LatLng(21.0302275,
						105.8649445), 12));

		mClusterManager = new ClusterManager<ObjectMap>(getActivity(), getMap());
		mClusterManager.setRenderer(new Maprender(getActivity()
				.getApplicationContext(), mMap, mClusterManager));
		getMap().setOnCameraChangeListener(mClusterManager);
		getMap().setInfoWindowAdapter(mClusterManager.getMarkerManager());

		getMap().setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

			@Override
			public void onInfoWindowClick(Marker marker) {
				// TODO Auto-generated method stub
				final Intent intent = new Intent(getActivity()
						.getApplicationContext(), ActivityViewItemMap.class);
				intent.putExtra("input", "object");
				intent.putExtra("object", myObject.getUploadTable());

				new Thread(new Runnable() {

					@Override
					public void run() {

						startActivity(intent);
					}
				}).start();
			}
		});

		// mClusterManager.getClusterMarkerCollection().setOnInfoWindowAdapter(
		// new MyCustomAdapterForClusters());
		mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(
				new MarkerInfoWindowAdapter());

		getMap().setOnMarkerClickListener(mClusterManager);

		mClusterManager
				.setOnClusterClickListener(new OnClusterClickListener<ObjectMap>() {
					@Override
					public boolean onClusterClick(Cluster<ObjectMap> cluster) {

						return false;
					}
				});
		mClusterManager
				.setOnClusterItemClickListener(new OnClusterItemClickListener<ObjectMap>() {
					@Override
					public boolean onClusterItemClick(ObjectMap _myObject) {
						myObject = _myObject;
						return false;
					}
				});
		new AsynctaskLoadMap().execute();
	}

	public void LoadDataMap() {
		new AsynctaskLoadMap().execute();
	}

	private void addItems(ObjectMap item) {
		mClusterManager.addItem(item);
	}

	public class MarkerInfoWindowAdapter implements InfoWindowAdapter {

		ImageLoader imageloader;
		DisplayImageOptions options;
		Marker marker;

		public MarkerInfoWindowAdapter() {

			imageloader = ImageLoader.getInstance();
			options = new DisplayImageOptions.Builder()
					.showImageOnLoading(R.drawable.ic_action_camera)
					.showImageForEmptyUri(R.drawable.ic_action_group)
					.showImageOnFail(R.drawable.ic_action_person)
					.cacheInMemory(true).cacheOnDisk(true)
					.considerExifParams(true)
					.displayer(new RoundedBitmapDisplayer(0)).build();
		}

		@Override
		public View getInfoWindow(final Marker marker) {
			this.marker = marker;
			View view = getActivity().getLayoutInflater().inflate(
					R.layout.infowindow_layout, null);

			final ImageView markerIcon = (ImageView) view
					.findViewById(R.id.ivImage_general);
			// TextView tvname = (TextView) view
			// .findViewById(R.id.tvname_object);
			final ProgressBar progressBar = (ProgressBar) view
					.findViewById(R.id.loading);

			imageloader.displayImage(myObject.getUploadTable().getImage1(),
					markerIcon, options, new SimpleImageLoadingListener() {

						@Override
						public void onLoadingStarted(String imageUri, View view) {
							progressBar.setVisibility(View.VISIBLE);
						}

						@Override
						public void onLoadingFailed(String imageUri, View view,
								FailReason failReason) {
							progressBar.setVisibility(View.GONE);
						}

						@Override
						public void onLoadingComplete(String imageUri,
								View view, Bitmap loadedImage) {
							progressBar.setVisibility(View.GONE);
							super.onLoadingComplete(imageUri, view, loadedImage);
							getInfoContents(marker);
						}
					});

			return view;
		}

		@Override
		public View getInfoContents(final Marker marker) {
			if (this.marker != null && this.marker.isInfoWindowShown()) {
				this.marker.hideInfoWindow();
				this.marker.showInfoWindow();
			}
			return null;
		}

	}

	protected class AsynctaskLoadMap extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			listuploadtable = db.getAllUploadTable();
			mClusterManager.clearItems();
			for (UploadTable uploadtable : listuploadtable) {
				addItems(new ObjectMap(uploadtable));

			}

			return null;
		}
	}

	private class Broasdcast extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			if (intent.getAction().equals("loadData")) {
				new AsynctaskLoadMap().execute();
			}
		}

	}

	@SuppressLint("DefaultLocale")
	private void search(String key) {
		listSeached.clear();
		int count = 0;
		for (UploadTable uploadtable : listuploadtable) {
			if (uploadtable.getName().toLowerCase().contains(key.toLowerCase())) {
				listSeached.add(new ObjectMap(uploadtable));
				count++;
			}
			if (count == 5)
				break;
		}
	}
}
